package com.gitee.aurora.engine.dao.impl;

import com.balloon.springboot.datasource.aop.DataSourceRouteKey;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gitee.aurora.core.comm.AuroraJdbcTemplate;
import com.gitee.aurora.core.comm.AuroraNamedParameterJdbcTemplate;
import com.gitee.aurora.core.utils.*;
import com.gitee.aurora.engine.dao.SjzxCheckDao;

import com.gitee.aurora.engine.po.LogResult;
import com.gitee.aurora.engine.po.RulesLogResult;
import com.gitee.aurora.engine.vo.DataCheckVo;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;


import javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


/**
 * author: jiangfuxiao
 * Date:2022/9/2 11:47
 */
@Repository("sjzxCheckDaoImpl")
public class SjzxCheckDaoImpl implements SjzxCheckDao {

    @Autowired
    private AuroraJdbcTemplate auroraJdbcTemplate;

    @Autowired
    private AuroraNamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    private DataSource dataSource;

    /**
     * PO路径
     */
    private static final String PO_PATH = "com.gitee.aurora.engine.po.";


    @Override
    public List queryTableDataByIds(DataCheckVo vo ) {

        if (CollectionUtils.isEmpty(vo.getIds())){
            return null;
        }

        StringBuilder sql = new StringBuilder();
        Map<String,Object> args = new HashMap<>();
        List list = new ArrayList<>();
        sql.append(" SELECT * FROM ");
        sql.append(vo.getTableName());
        sql.append("  WHERE 1=1 ");
        args.put("ids",vo.getIds());
        sql.append("  AND S_ID IN (:ids) ");
        try {
            list = jdbcTemplate.queryForList(sql.toString(),args);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }


    @Override
    @DataSourceRouteKey(type="secondMysqlDB")
    public RulesLogResult queryTableRuleByTableId(RulesLogResult result ) {
        List<Object>  paramList = new ArrayList<>();
        int[] types = new int[]{java.sql.Types.VARCHAR,java.sql.Types.VARCHAR,java.sql.Types.VARCHAR};
        StringBuilder sql = new StringBuilder();
        List<RulesLogResult> list = new ArrayList<>();
        sql.append(" SELECT * FROM RULES_LOG_RESULT");
        sql.append("  WHERE 1=1 ");
        sql.append("  AND `TABLEID` = ?");
        paramList.add(result.getTableId());
        sql.append("  AND `TABLENAME` = ?");
        paramList.add(result.getTableName());
        sql.append("  AND `DEPTCODE` = ?");
        paramList.add(result.getDeptCode());
        sql.append("  AND `COLUMN`  = ?");
        paramList.add(result.getColumn());
        try {
            list = auroraJdbcTemplate.queryForMapToList(sql.toString(),paramList.toArray(),types,RulesLogResult.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!CollectionUtils.isEmpty(list)){
            return  list.get(0);
        }
        return null;
    }

    @Override
    public ResultVO insertData(DataCheckVo vo)  {
        ObjectMapper mapper = new ObjectMapper();
        try {
            String code = StringProcessUtils.firstCodeUpperConvertJavaHump(vo.getTableName().toLowerCase());
            List<LinkedHashMap<String,Object>> dataList = (List<LinkedHashMap<String,Object>>) mapper.readValue(vo.getListStr(), List.class);
            dataList.forEach((v -> {
                if (!v.containsKey("sId")) {
                    v.put("sId", v.get("S_ID"));
                }
            }));
            List resultList = new ArrayList();
            for (Object o: dataList) {
                resultList.add(MapToObj.mapUpperCaseFieldToObj((Map)o, Class.forName(PO_PATH + code)));
            }
            int[] ints = auroraJdbcTemplate.batchInsertForTableName(auroraJdbcTemplate.getDataSource(),vo.getTableName(),resultList);
            return ResultVOUtils.success(ints);
        }catch (Exception e){
            e.printStackTrace();
            return ResultVOUtils.error("批量插入执行错误");
        }
    }


    @Override
    @DataSourceRouteKey(type="secondMysqlDB")
    public String querySqlStr(String ip,String tableName) {
        List<Object>  paramList = new ArrayList<>();
        int[] types = new int[]{java.sql.Types.VARCHAR,java.sql.Types.VARCHAR};
        StringBuilder sql = new StringBuilder();
        sql.append("  SELECT T2.PT_SQL AS sqlStr FROM ");
        sql.append("  TAB_PTCJ_CONFIG T1              ");
        sql.append("  LEFT JOIN TAB_PT_CONFIG  T2     ");
        sql.append("  ON T1.S_CODE = T2.S_CODE        ");
        sql.append("  WHERE 1=1                       ");
        sql.append("  AND T2.PT_CODE=1                ");

        if (StringUtils.isNotBlank(ip)){
            sql.append("  AND T1.PT_IP= ?                 ");
            paramList.add(ip);
        }
        if (StringUtils.isNotBlank(tableName)){
            sql.append("  AND T2.PT_TABLE= ?                ");
            paramList.add(tableName);
        }
        try {
            List list = auroraJdbcTemplate.queryForList(sql.toString(),paramList.toArray(),types,String.class);
            if (!CollectionUtils.isEmpty(list)){
                return (String) list.get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public List queryTableDataByCode(String tableName) {
        List list = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        builder.append(" SELECT  DATE_FORMAT( MAX(GXSJ),\"%Y-%m-%d %H:%i:%S\") GXSJ FROM ");
        builder.append(tableName);
        try {
            list = auroraJdbcTemplate.queryForList(builder.toString(),String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }

    @Override
    @DataSourceRouteKey(type="secondMysqlDB")
    public void saveRulesLogResult(List<RulesLogResult> insertData) {
        try {
            auroraJdbcTemplate.batchInsertForTableName(auroraJdbcTemplate.getDataSource(),"RULES_LOG_RESULT",insertData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @DataSourceRouteKey(type="secondMysqlDB")
    public void saveLogResult(List<LogResult> insertData) {
        try {
            auroraJdbcTemplate.batchInsertForTableName(auroraJdbcTemplate.getDataSource(),"LOG_RESULT",insertData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @DataSourceRouteKey(type="secondMysqlDB")
    public Map<String, Object>  getRule(String tableName,String deptCode){
        String sql = "SELECT ID,TABLE_NAME,RULE FROM TAB_RULE WHERE TABLE_NAME = ? AND DEPT_CODE = ?";
        int[] types = new int[]{Types.VARCHAR, Types.VARCHAR};
        try {
            Map<String, Object> map = auroraJdbcTemplate.queryForMap(sql, new Object[]{tableName, deptCode}, types);
            return map;
        }catch (Exception e){
            return null;
        }
    }


    @Override
    @DataSourceRouteKey(type="secondMysqlDB")
    public List queryTable() {
        List list = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        builder.append(" SELECT  TABLE_CODE AS tabCode, TABLE_CODE_NAME AS tabName  FROM  TAB_TABLE_CONFIG");
        try {
            list = auroraJdbcTemplate.queryForList(builder.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }

    @Override
    @DataSourceRouteKey(type="secondMysqlDB")
    public   List<Map<String, Object>> queryAllBaqIp(String sjzxIp) {
        StringBuilder sql = new StringBuilder();

        int[] types = new int[]{Types.VARCHAR};

        sql.append(" SELECT                                                  ");
        sql.append(" T2.PT_IP AS baqIp                                       ");
        sql.append(" FROM                                                    ");
        sql.append("(SELECT S_CODE FROM  TAB_PTCJ_CONFIG WHERE PT_IP = ? ) T1");
        sql.append(" LEFT JOIN TAB_PTCJ_CONFIG T2 ON T1.S_CODE = T2.F_CODE   ");
        sql.append(" LEFT JOIN TAB_PT_CONFIG T3 ON T2.S_CODE = T3.S_CODE     ");
        sql.append(" WHERE T3.PT_CODE = 1                                    ");
        sql.append(" GROUP BY T3.S_CODE                                      ");

        try {
            List<Map<String, Object>> map = auroraJdbcTemplate.queryForList(sql.toString(), new Object[]{sjzxIp}, types);
            return map;
        }catch (Exception e){
            return null;
        }
    }

    @Override
    public ResultVO getDBTableField(String tableName) {
        List<String> dbFieldNameList = null;
        try {
            dbFieldNameList = new DBUtils(dataSource).getDBFieldNameList(tableName);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return ResultVOUtils.success(dbFieldNameList);
    }


}
